//
// Ephi - simulation of magnetic fields and particles
// Copyright (C) 2007 Indrek Mandre <indrek(at)mare.ee>
// For more information please see http://www.mare.ee/indrek/ephi/
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "statics.hpp"
#include "screen.hpp"
#include "dynamics.hpp"

// test for b field from the center of a finite straight wire

#define LENGTH 6.0
#define RADIUS 1.0
#define CURRENT 5000
#define DIST0 0.01
#define DIST1 0.1
#define DIST2 0.65
#define DIST3 3.65
#define DIST4 8.65
#define B_DIST0 0.0999994444490740
#define B_DIST1 0.0099944490697916
#define B_DIST2 0.0015035740615797
#define B_DIST3 0.0001739630344319
#define B_DIST4 0.0000378812972021
#define ALLOWED_FACTOR 1000.0 // allow difference by 1/1000 worth

static void test_against (const char *where, const vect3d& bf, const vect3d& t_bf)
{
  prec_t diff = (bf - t_bf).length();
  if ( diff > t_bf.length() / ALLOWED_FACTOR )
    {
      printf ("ERROR_%s=fields differ too much\n", where);
    }
  else
    {
      printf ("OK_%s=fields match up\n", where);
    }
  char buf[128];
  printf ("BF_%s=%s\n", where, bf.sprint (buf));
  printf ("TBF_%s=%s\n", where, t_bf.sprint (buf));
  printf ("MARGIN_%s=%g (%g%%)\n", where, prec2double(diff), prec2double(100.0 * diff / t_bf.length()));
}

int main (int argc, char *argv[])
{
  Statics statics;
  ElectroDynamics dyn(statics);
  statics.addStaticElement (new StaticLine (5000,
      vect3d(0, 0, -LENGTH/2-1), // add a slight offse to test our nerves
      vect3d(0, 0, LENGTH/2-1), 0.05));

  vect3d bf;
  dyn.getBField (vect3d(DIST0, 0, -1), bf);
  test_against ("DIST0", bf, vect3d (0, B_DIST0, 0));
  dyn.getBField (vect3d(DIST1, 0, -1), bf);
  test_against ("DIST1", bf, vect3d (0, B_DIST1, 0));
  dyn.getBField (vect3d(DIST2, 0, -1), bf);
  test_against ("DIST2", bf, vect3d (0, B_DIST2, 0));
  dyn.getBField (vect3d(DIST3, 0, -1), bf);
  test_against ("DIST3", bf, vect3d (0, B_DIST3, 0));
  dyn.getBField (vect3d(DIST4, 0, -1), bf);
  test_against ("DIST4", bf, vect3d (0, B_DIST4, 0));

  return 0;
}

